package com.ws.universal.tools.livedatabus;


import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author:ws 中间人 代理
 * @date: 2019/10/24 8:50
 * @desc
 */
public class LiveDataBusX {

    //双重锁模式
    //线程安全，延迟初始化。这种方式采用双锁机制，安全且在多线程情况下能保持高性能。
    private volatile static LiveDataBusX liveDataBusX;
    //创建一个容器 用来转载所有的订阅者
    private Map<String, BusMutableLiveData<Object>> bus;

    public LiveDataBusX() {
        bus = new HashMap<>();
    }

    public static LiveDataBusX getInstace() {
        if (liveDataBusX == null) {
            synchronized (LiveDataBus.class) {
                if (liveDataBusX == null) {
                    liveDataBusX = new LiveDataBusX();
                }
            }
        }
        return liveDataBusX;
    }

    /**
     * 注册订阅者
     */
    public synchronized <T> BusMutableLiveData<T> with(String key, Class<T> type) {
        //如果不包含 就加进去
        if (!bus.containsValue(key)) {
            bus.put(key, new BusMutableLiveData<Object>());
        }
        return (BusMutableLiveData<T>) bus.get(key);
    }

    public static class BusMutableLiveData<T> extends MutableLiveData<T> {
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            super.observe(owner, observer);
            //开始进行hook 让 observer.mLastVersion = mVersion
            try {
                hook((Observer<T>) observer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        private void hook(Observer<T> observer) throws Exception {
            //获取LiveDatamVersion成员变量的反射对象
            Class<LiveData> liveDataClass = LiveData.class;
            //通过类对象获取到mVersion成员变量的反射
            Field mVersionField = liveDataClass.getDeclaredField("mVersion");
            //打开权限
            mVersionField.setAccessible(true);

            //去获取到 mObservers 成员变量的反射
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            //打开权限
            mObserversField.setAccessible(true);
            //获取到 mObservers 在LiveData中的值
            Object mObservers = mObserversField.get(this);
            //通过 mObservers 的值去获取它的get方法
            Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);
            //打开权限
            get.setAccessible(true);
            //去执行get方法
            Object invokeEntry = get.invoke(mObservers, observer);
            //定义一个 ObserverWropper 的空对象
            Object observerWropper = null;
            if (invokeEntry != null && invokeEntry instanceof Map.Entry) {
                observerWropper = ((Map.Entry) invokeEntry).getValue();
            }
            if (observerWropper == null) {
                throw new NullPointerException("observerWropper 不能为空");
            }


            //获取到 observerWropper 里面的 LastVersion 的成员变量
            Field mLastVersionField = observerWropper.getClass().getSuperclass().getDeclaredField("mLastVersion");
            //打开权限
            mLastVersionField.setAccessible(true);
            //先获取到Version的值
            Object object = mVersionField.get(this);
            //把他 赋给mLastVersion
            mLastVersionField.set(observerWropper, object);

        }
    }


}
